beta_changesfandomcom-20200213-history
MS-DOS:1.25:Z-100 OEM:1.01:8-11-1983/disk02/BDSKLA.ASM
Disk change test assembler source file. File content ; ; BIOS_DSKCHG - Disk change test ; ; Check if the specified disk has been changed. ; ; Call with: ; AL = drive number ; ; Returns: ; CY = 0 (normal exit) ; = -1 if disk has been changed ; AH = 0 if it is not known if disk is changed ; = 1 if disk could not have been changed ; AL = drive number (can change) ; CY = 1 (error exit) ; AL = error code ; ; No other registers are changed. ; ; ; BIOS_DSKCHG handles device mapping for the 8" drives, since ; bit densities can change, and BIOS_MAPDEV won't be able to ; get a valid FATID. ; ; Last modified: 7/29/82 - dtp ; BIOS_DSKCHG PROC FAR PUSH DS ; Save regs PUSH DI PUSH CS ; Set up DS POP DS MOV AH,AL ; Drive number in proper reg MOV AL,DSK_MAPDSK ; Get function PUSH CS ; Make call into far call CALL NEAR PTR BIOS_DSKFUNC ; Map drive number MOV DI,AX ; Get drive number AND DI,0FFH ; Isolate it SHL DI,1 ; Convert it to a word index MOV DI,WORD PTR DSK_TPTRDI ; Get addr of DSK entry IF WINCH CMP AL,MAXDSK8 ; > 8" disk drive? JB DSKCHG0 ; Nope, is 5 or 8 ; Is > 8" disk drive, must be a winchester, DI = table entry TEST BYTE PTR DI+DSK_FLAG,DSK_ASN JZ BIOS_DSKCHGNR ; Not assigned, show not ready TEST BYTE PTR DI+DSK_SEL,SBAEFLNF ; Formatted? JNZ BIOS_DSKCHGNR ; Nope, show not ready MOV BYTE PTR BIOS_DSKCHV,1 JMP NEAR PTR BIOS_DSKCHG2 ENDIF ; Check if drive is still selected, if so assume disk has not been changed DSKCHG0: MOV BYTE PTR BIOS_DSKCHV,0 ; Assume don't know if disk changed CLI ; Disable interrupts MOV AH,BYTE PTR DSK_FLAGDI ; Get falg byte TEST AH,DSK_FDC ; Force disk change ? JNZ BIOS_DCHG ; Yes, skip TEST BYTE PTR DSKT_FG,0FFH ; Has select timed out ? JZ BIOS_DCHG ; Yes, skip CMP DI,DSK_LDRIVE ; Is last drive the same as the current one ? JNE BIOS_DCHG ; No, skip MOV BYTE PTR BIOS_DSKCHV,1 ; Yes, show disk hasn't changed BIOS_DCHG: STI ; Turn interrupts back on AND AH,NOT DSK_FDC ; Remove force disk change(if present) MOV BYTE PTR BIOS_DSKCHGA,AH ; Save flag value ; Make drive look single sided for status and restore call. AND AH,NOT DSK_FDS ; Turn off double sided MOV BYTE PTR DSK_FLAGDI,AH ; Store back flag byte MOV BYTE PTR DSKPR+DSKPR_DRIVE,AL ; Store drive number PUSH ES ; Save regs PUSH BX MOV BX,CS ; Set up ES:BX to point to DSK parm pkt MOV ES,BX MOV BX,OFFSET DSKPR MOV AL,DSK_STATUS ; Get function PUSH CS ; Make call into far call CALL NEAR PTR BIOS_DSKFUNC ; Get status of drive, any errors ? JC BIOS_DSKCHG0 ; Yes, skip TEST BYTE PTR BIOS_DSKCHV,1 ; Is disk still selected ?(must clear CY) JNZ BIOS_DSKCHG0 ; Yes, don't do I/O PUSH AX ; Save status in AH MOV AL,DSK_RESET ; Get function PUSH CS ; Make call a far call CALL NEAR PTR BIOS_DSKFUNC ; Restore head POP AX ; Restore status BIOS_DSKCHG0: POP BX ; Restore regs POP ES MOV AL,BYTE PTR BIOS_DSKCHGA ; Get saved flags MOV BYTE PTR DSK_FLAGDI,AL ; Restore original flag MOV AL,BYTE PTR DSKPR+DSKPR_DRIVE ; Get drive number JNC BIOS_DSKCHG0A ; If no 'C' set (no error) ; 'C' set, must be invalid or not ready drive BIOS_DSKCHGNR: STC MOV AL,DSKE_NREADY ; Show error JMP SHORT BIOS_DSKCHG2 ; Bail out ; Check for 5" disk drive, AH has auxilary status, AL has drive index BIOS_DSKCHG0A: CMP AL,MAXDSK5 ; Is disk a 5 incher ? JB BIOS_DSKCHG1A ; Yes, go to it ; Disk is 8", check for number of sides ; Set up DI as a table pointer MOV DI,AX ; Get drive index AND DI,0FFH ; Issolate drive number SHL DI,1 ; Convert it to word index MOV DI,DSK_TPTRDI ; Get addr of DSK entry TEST AH,AS2S ; Is disk double sided ? JNZ BIOS_DSKCHGDS ; Yes, go do it ; Set up of single sided/single density disks AND BYTE PTR DSK_FLAGDI,NOT DSK_FDS ; Clear double sided OR BYTE PTR DSK_SELDI,CONSD ; Make single density MOV WORD PTR DSK_BPSDI,128 ; Set sector size MOV WORD PTR DSK_BPWTDI,5365 ; Set track size MOV WORD PTR DSK_BPRTDI,5365 MOV BYTE PTR DSK_SPTDI,26 ; Set sectors/track JMP SHORT BIOS_DSKCHG1A ; Skip other case ; Set up of double sided/double density disks BIOS_DSKCHGDS: ADD AL,OFFSET DSK_BMPVAL AND BYTE PTR DSK_SELDI,NOT CONSD ; Make double density OR BYTE PTR DSK_FLAGDI,DSK_FDS ; Make double sided MOV WORD PTR DSK_BPSDI,1024 ; Set sector size MOV WORD PTR DSK_BPWTDI,10729 ; Set track size MOV WORD PTR DSK_BPRTDI,10729 MOV BYTE PTR DSK_SPTDI,8 ; Set sectors/track BIOS_DSKCHG1A: CLC ; Clear "C" to show no error BIOS_DSKCHG2: POP DI ; Recover DI MOV AH,BIOS_DSKCHV ; Get change flag POP DS ; Recover DS RET ; and return BIOS_DSKCHGA DB ? ; Save for DSK_FLAG BIOS_DSKCHV DB ? ; Disk change value BIOS_DSKCHG ENDP ; ; BIOS_MAPDEV - Map disk I/O drivers ; ; Call with: ; AL = I/O driver used to read FAT ; AH = First byte of FAT (range F8 to FF) ; ; Returns: ; AL = I/O driver for this diskette and drive ; ; No other registers are changed. ; BIOS_MAPDEV PROC FAR PUSH DS ; Save DS and set up new DS PUSH CS POP DS ; Determine drive type CMP AL,MAXDSK5 ; Is drive an 8 incher or winchester ? JNL BIOS_MAPDEV2 ; Yes, nothing to do ; Drive is a 5 incher PUSH SI ; Save regs PUSH BX MOV SI,AX ; Get drive index AND SI,0FFH ; Issolate index SHL SI,1 ; Convert to word index MOV SI,DSK_TPTRSI ; Get addr of DSK entry MOV BL,BYTE PTR DSK_FLAGSI ; Get current flags AND BL,NOT (DSK_FDS OR DSK_FDP) ; Clear setable flags ; Set up disk table to assume double sided 80 track MOV BH,DSK_FDS ; Show as double sided MOV BYTE PTR DSK_MAXTSI,80 ; Set max track number ; Now see if actually is single sided 40 track CMP AH,0FDH ; Was assumption correct ? JE BIOS_MAPDEV1 ; Yes, skip to end ; Was a small disk, patch tables MOV BH,DSK_FDP ; Show as double step MOV BYTE PTR DSK_MAXTSI,40 ; Set number of tracks ADD AL,OFFSET DSK_BMPVAL ; Map to next set of slots ; Now see if we really must double step PUSH AX ; Save AL value PUSH DX ; Save DX CALL DSK_IAS ; Read auxiliary status TEST AL,AS96T ; See if drives are 96tpi POP DX ; Restore regs POP AX JNZ BIOS_MAPDEV0 ; Yes, leave at double step ; Drives are really 48tpi MOV BH,0 ; Clear double step ; Now see if single or double sided BIOS_MAPDEV0: CMP AH,0FEH ; Single sided? JZ BIOS_MAPDEV1 ; Yes, skip ; Disk is double sided, patch flag byte OR BH,DSK_FDS ; Add in double sided ADD AL,OFFSET (DSK_BMPVAL1-DSK_BMPVAL) ; Map drive number again BIOS_MAPDEV1: OR BH,BL ; Put together flag bits MOV BYTE PTR DSK_FLAGSI,BH ; Store new flag bits POP BX ; Recover regs POP SI BIOS_MAPDEV2: POP DS RET BIOS_MAPDEV ENDP �������������������������